﻿using System;
using System.Linq;
using CodeCounsel.SharePoint.RibbonDesigner.Model;
using System.Xml.Linq;
using System.Windows.Input;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.XmlEditor;
using System.Linq.Expressions;
using System.ComponentModel;
using System.Threading;

namespace CodeCounsel.SharePoint.RibbonDesigner.ViewModel
{
    public class MasterViewModel
        : BaseViewModel
    {
        // the model
        CommandUIDocument _definition;
        // a child view model
        RibbonViewModel _viewModel;
        Semaphore _viewReloadLock;

        public RibbonViewModel Ribbon
        {
            get { return _viewModel; }
            private set
            {
                if (value != _viewModel)
                {
                    _viewModel = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("Ribbon"));
                }
            }
        }

        public MasterViewModel(CommandUIModel domainModel)
        {
            _viewReloadLock = new Semaphore(1, 1);
            CommandUIDocument uiDefinition = domainModel.CommandUIDefinition;
            _definition = uiDefinition;
            RibbonTemplates ribbonTemplates = null;
            Templates templates = uiDefinition.CommandUI.Templates;
            Ribbon ribbon = ExtensionManager.GetReplacedChild<Ribbon>(uiDefinition.CommandUI);
            if (templates != null)
            {
                ribbonTemplates = ExtensionManager.GetReplacedChild<RibbonTemplates>(templates);
            }
            Ribbon = new RibbonViewModel(
                ribbon,
                ribbonTemplates);
            domainModel.ElementsDefinitionChanged += new EventHandler(DomainModel_ElementsDefinitionChanged);
        }

        void DomainModel_ElementsDefinitionChanged(object sender, EventArgs e)
        {
            ReloadViewModel();
        }

        void ReloadViewModel()
        {
            Ribbon ribbon = ExtensionManager.GetReplacedChild<Ribbon>(_definition.CommandUI);

            if (_viewReloadLock.WaitOne(0))
            {
                try
                {
                    RunUI(delegate
                    {
                        string tabId = _viewModel.SelectedTab != null ?
                            _viewModel.SelectedTab.Id :
                            null;
                        Ribbon = new RibbonViewModel(
                            ribbon,
                            _definition.CommandUI.Templates.RibbonTemplates);
                        if (tabId != null)
                        {
                            TabViewModel tab = Ribbon.Tabs.Where(
                                t => t.Id == tabId).FirstOrDefault();
                            if (tab != null)
                            {
                                Ribbon.SelectedTab = tab;
                            }
                        }
                    });
                }
                finally
                {
                    _viewReloadLock.Release();
                }
            }
        }
    }
}
